package controller

import (
	"time"

	. "gddgame.cc/galaxy/common/dsl/web"
	"gddgame.cc/galaxy/project/breeder/breeder/cooperated"
	"gddgame.cc/galaxy/project/breeder/breeder/model"
	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/def"
	"gddgame.cc/galaxy/utils/orm"
)

func ValidAndUseUnitProp(context def.Context, userUnitId string, propId int, needConsume bool) error {
	var userUnit model.UserUnit
	if ok, _ := model.UserUnitModel.PK(userUnitId).One(&userUnit); !ok {
		return ValidException(Center.LanguageKey("NOT_EXIST_UNIT"))
	}
	target := -1
	for index, item := range userUnit.Props {
		if item == nil {
			continue
		}
		if item.PropId != propId {
			continue
		}
		if item.Number == 0 {
			continue
		}
		target = index
		goto Success
	}
	return ValidException(Center.LanguageKey("NOT_PROP_IN_UNIT"))
Success:
	if !needConsume {
		return nil
	}
	userUnit.Props[target].Number -= 1
	if userUnit.Props[target].Number == 0 {
		userUnit.Props[target] = nil
	}

	if err := Env.SingleClean("unit/"+utils.ToString(userUnit.Id), func() error {
		data := map[string]interface{}{
			"props": userUnit.Props,
		}
		if _, err := model.UserUnitModel.PK(userUnit.Id).Update(data); err != nil {
			return SystemExceptionDetail("更新错误", err)
		}
		return nil
	}, false); err != nil {
		return err
	}
	return nil
}

func AddProps(context def.Context, props map[int]int, number int, user *model.User) error {
	if props == nil || len(props) == 0 {
		return nil
	}
	var err error
	var uProps []model.UserProp
	var propIds []int
	var propMap map[int]*model.UserProp
	// 添加获取的道具
	if len(props) == 0 {
		return nil
	}
	propIds = make([]int, 0, len(props))
	for key, _ := range props {
		propIds = append(propIds, key)
	}
	if _, err = model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("in", "prop_id", propIds).Find(&uProps); err != nil {
		return SystemExceptionDetail("查找用户道具失败", err)
	}
	if len(uProps) > 0 {
		propMap = make(map[int]*model.UserProp, len(uProps))
		for _, prop := range uProps {
			propMap[prop.PropId] = &prop
		}
	} else {
		propMap = map[int]*model.UserProp{}
	}

	for key, value := range props {
		if value <= 0 {
			continue
		}
		prop := Center.PropMap[key]
		uProp, ok := propMap[key]
		if ok {
			// 保存增量
			uProp.Number = value * number
		} else {
			uProps = append(uProps, model.UserProp{
				Id:     0,
				UserId: user.Id,
				PropId: prop.Id,
				Number: value * number,
			})
		}
	}
	for _, uProp := range uProps {
		if uProp.Id == 0 {
			if _, err = model.UserPropModel.Query().Save(true, &uProp); err != nil {
				return SystemExceptionDetail("添加道具失败", err)
			}
		} else {
			if _, err = model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
				"number": &orm.UpdateOperate{Operate: "-", Value: uProp.Number},
			}); err != nil {
				return SystemExceptionDetail("添加道具失败", err)
			}
		}

	}
	return nil
}

func ValidProps(context def.Context, props map[int]int, number int, user *model.User) ([]model.UserProp, error) {
	if props == nil || len(props) == 0 {
		return nil, nil
	}
	var err error
	var uProps []model.UserProp
	var propIds []int
	// 添加获取的道具
	if len(props) == 0 {
		return nil, nil
	}
	propIds = make([]int, 0, len(props))
	for key, _ := range props {
		propIds = append(propIds, key)
	}
	if _, err = model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("in", "prop_id", propIds).Find(&uProps); err != nil {
		return nil, SystemExceptionDetail("查找用户道具失败", err)
	}
	if len(uProps) < len(props) {
		return nil, SystemExceptionDetail("道具数量不够", err)
	}
	for _, uProp := range uProps {
		value := props[uProp.Id]
		if uProp.Number < value*number {
			return nil, SystemExceptionDetail("道具数量不够", err)
		}
	}
	return uProps, nil
}

func RemoveProps(context def.Context, props map[int]int, number int, uProps []model.UserProp) error {
	for _, uProp := range uProps {
		value := props[uProp.Id]
		if uProp.Number == value*number {
			if _, err := model.UserPropModel.PK(uProp.Id).Delete(); err != nil {
				return SystemExceptionDetail("扣除道具失败", err)
			}
		} else {
			if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
				"number": &orm.UpdateOperate{Operate: "-", Value: props[uProp.Id] * number},
			}); err != nil {
				return SystemExceptionDetail("扣除道具失败", err)
			}
		}
	}
	return nil
}

func GetProps(context def.Context, userId int, updateTime *time.Time) ([]model.UserProp, error) {
	var err error
	var uProps []model.UserProp
	query := model.UserPropModel.Query().Where("=", "user_id", userId)
	if updateTime != nil && updateTime.After(Env.Time()) {
		query.Where(">", "update_time", updateTime)
	}
	if _, err = query.Find(&uProps); err != nil {
		return nil, SystemExceptionDetail("查找用户道具失败", err)
	}

	return uProps, nil
}

func BuyProp(context def.Context, shopPropId int, number int, user *model.User, account *cooperated.Account) error {
	shopProp := Center.ShopPropMap[shopPropId]
	prop := shopProp.Prop
	if !ValidRequire(context, shopProp.RequireSlice, user, account, nil, nil) {
		return ValidException("不满足购买条件")
	}
	var uProp model.UserProp
	exist, _ := model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("=", "prop_id", prop.Id).One(&uProp)
	if ok, consumeData := ValidConsume(context, shopProp.ConsumeSlice, number, user, nil); !ok {
		return ValidException("无法购买")
	} else {
		if err := UpdateConsume(context, consumeData, user, nil); err != nil {
			return err
		}
	}
	if !exist {
		uProp = model.UserProp{
			Id:     0,
			UserId: user.Id,
			PropId: prop.Id,
			Number: number,
		}
		if _, err := model.UserPropModel.Query().Save(true, &uProp); err != nil {
			return SystemExceptionDetail("添加道具失败", err)
		}
	} else {
		if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
			"number": &orm.UpdateOperate{Operate: "+", Value: number},
		}); err != nil {
			return SystemExceptionDetail("添加道具失败", err)
		}
	}

	return nil
}

func SellProp(context def.Context, userPropId int, number int, user *model.User) (*model.Prop, error) {
	var uProp model.UserProp
	ok, _ := model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("=", "id", userPropId).One(&uProp)
	if !ok {
		return nil, ValidException("道具不存在")
	}
	if uProp.Number < number {
		return nil, ValidException("道具数量不足")
	}
	prop := Center.PropMap[uProp.PropId]
	if !prop.CanSell {
		return nil, ValidException("道具不可出售")
	}
	if uProp.Number == number {
		if _, err := model.UserPropModel.PK(uProp.Id).Delete(); err != nil {
			return nil, SystemExceptionDetail("出售道具失败", err)
		}
	} else {
		if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
			"number": &orm.UpdateOperate{Operate: "-", Value: number},
		}); err != nil {
			return nil, SystemExceptionDetail("出售道具失败", err)
		}
	}

	if !UpdateReceive(context, prop.SellReceiveSlice, number, user) {
		return nil, ValidException("无法执行")
	}

	return prop, nil
}

func UseProp(context def.Context, userPropId int, user *model.User, account *cooperated.Account) (*model.Prop, error) {
	var uProp model.UserProp
	ok, _ := model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("=", "id", userPropId).One(&uProp)
	if !ok {
		return nil, ValidException("道具不存在")
	}
	if uProp.Number <= 0 {
		return nil, ValidException("道具数量不足")
	}
	prop := Center.PropMap[uProp.PropId]
	if prop.Mode != model.UseSelfPropMode && prop.Mode != model.DirectPropMode {
		return nil, ValidException("道具无法直接使用")
	}
	if !ValidRequire(context, prop.RequireSlice, user, account, nil, nil) {
		return nil, ValidException("不满足使用条件")
	}

	if uProp.Number == 1 {
		if _, err := model.UserPropModel.PK(uProp.Id).Delete(); err != nil {
			return nil, SystemExceptionDetail("使用道具失败", err)
		}
	} else {
		if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
			"number": &orm.UpdateOperate{Operate: "-", Value: 1},
		}); err != nil {
			return nil, SystemExceptionDetail("使用道具失败", err)
		}
	}

	if prop.Mode == model.UseSelfPropMode {
		if !UpdateReceive(context, prop.ReceiveSlice, 1, user) {
			return nil, ValidException("无法执行")
		}
	}

	return prop, nil
}
func PutOnProp(context def.Context, userPropId int, index int, number int, user *model.User, account *cooperated.Account, userUnit *model.UserUnit, unitInstance *cooperated.Unit) (err error) {
	var uProp model.UserProp
	ok, _ := model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("=", "id", userPropId).One(&uProp)
	if !ok {
		return ValidException("道具不存在")
	}
	if uProp.Number == 0 {
		return ValidException("道具数量不足")
	}

	prop := Center.PropMap[uProp.PropId]
	if prop.Mode != model.PutUnitPropMode {
		return ValidException("道具无法被安装")
	}

	if !ValidRequire(context, prop.RequireSlice, user, account, userUnit, unitInstance) {
		return ValidException("不满足使用条件")
	}
	if number == uProp.Number {
		if _, err := model.UserPropModel.PK(uProp.Id).Delete(); err != nil {
			return SystemExceptionDetail("扣除道具失败", err)
		}
	} else {
		if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
			"number": &orm.UpdateOperate{Operate: "-", Value: number},
		}); err != nil {
			return SystemExceptionDetail("扣除道具失败", err)
		}
	}
	if len(userUnit.Props) > index {
		if userUnit.Props[index] != nil {
			// 卸载已有道具
			if err := PutOutProp(context, userUnit.Props[index].PropId, index, user, userUnit); err != nil {
				return err
			}
		}
	}
	// 添加好装备，最后外部保存
	l := len(userUnit.Props)
	if index >= l {
		userUnit.Props = append(userUnit.Props, make([]*model.PropInUser, index-l+1)...)
	}
	userUnit.Props[index] = &model.PropInUser{
		PropId: prop.Id,
		Number: number,
	}
	return
}

func PutOutProp(context def.Context, propId int, index int, user *model.User, userUnit *model.UserUnit) (err error) {
	if len(userUnit.Props) > index {
		if userUnit.Props[index] == nil {
			return ValidException("未安装道具")
		}
	} else {
		return ValidException("未安装道具")
	}
	var uProp model.UserProp
	ok, _ := model.UserPropModel.Query().Where("=", "user_id", user.Id).Where("=", "prop_id", propId).One(&uProp)
	if ok {
		if _, err := model.UserPropModel.PK(uProp.Id).Update(map[string]interface{}{
			"number": &orm.UpdateOperate{Operate: "+", Value: userUnit.Props[index].Number},
		}); err != nil {
			return SystemExceptionDetail("卸载道具失败", err)
		}
	} else {
		uProp = model.UserProp{
			Id:     0,
			UserId: user.Id,
			PropId: propId,
			Number: userUnit.Props[index].Number,
		}
		if _, err := model.UserPropModel.Query().Save(true, &uProp); err != nil {
			return SystemExceptionDetail("卸载道具失败", err)
		}
	}

	// 移除装道具，最后外部保存
	userUnit.Props[index] = nil
	return
}
